package controllers

import (
	"errmsg"
	"errors"
	"fmt"
	"github.com/astaxie/beego/logs"
	"github.com/astaxie/beego/validation"
	"smart_home/api/models"
)

type FamilyController struct {
	BaseController
}

// @Title Create
// @Description 分享设备给家人
// @router /add [post]
func (c *FamilyController) Share() {
	var (
		mobile    int64
		sta       string
		err       error
		vali      validation.Validation
		eq        *models.Equipment
		toUser    *models.User
		is_repeat bool
		content   string
	)

	sta = c.GetString("sta")
	if mobile, err = c.GetInt64("mobile"); err != nil {
		logs.Info(err)
		c.Error(errmsg.ErrResponseParameter)
		return
	}

	// 数据验证
	vali = validation.Validation{}
	vali.Required(mobile, "mobile").Message("手机号码不能为空")
	vali.Mobile(mobile, "mobile").Message("手机号码为11为数字组成")
	vali.Required(sta, "sta").Message("sta不能为空")
	if vali.HasErrors() {
		logs.Info(vali.Errors[0])
		c.Error(vali.Errors[0])
		return
	}

	if mobile == c.User.Mobile {
		err = errors.New("不能分享给自己")
		logs.Info(err)
		c.Error(err)
		return
	}

	if eq, err = models.GetEquipmentBySta(sta); err != nil {
		logs.Info(err)
		c.Error(err)
		return
	}
	if eq.UserId != c.User.Id {
		logs.Info(errmsg.ErrResponseAuth)
		c.Error(errmsg.ErrResponseAuth)
		return
	}

	if toUser, err = models.GetUserByMobile(mobile); err != nil {
		logs.Info(err)
		c.Error(errmsg.ErrResponseSystem)
		return
	}
	if toUser == nil {
		err = errors.New("分享用户不存在")
		logs.Info(err)
		c.Error(err)
		return
	}

	// 判断用户是否已经存在分享
	if is_repeat, err = models.IsRepeatShare(sta, toUser.Id); err != nil {
		logs.Info(err)
		c.Error(errmsg.ErrResponseSystem)
		return
	}
	if is_repeat {
		err = errors.New("不能重复分享")
		logs.Info(err)
		c.Error(err)
		return
	}

	if err = models.AddFamily(c.User.Id, toUser.Id, sta); err != nil {
		logs.Info(err)
		c.Error(errmsg.ErrResponseFail)
		return
	}

	// 通知被分享用户
	content = fmt.Sprintf("%s给您分享了一个设备", c.User.NickName)
	// 推送消息
	models.PushMessage(toUser.Id, content, "invite")

	c.Success(nil)
}

// @Title my all family
// @Description 我的家人列表
// @router /all [get]
func (c *FamilyController) MyFamily(uid string) {
	var (
		lists, users []*models.User
		err          error
	)
	users = []*models.User{}
	if lists, err = models.GetMyFamilyUsers(c.User.Id); err != nil {
		logs.Error(err)
		c.Error(errmsg.ErrResponseSystem)
		return
	}
	users = append(users, c.User)
	if lists != nil {
		users = append(users, lists...)
	}

	c.Success(users)
}

type familyList struct {
	models.Family
	User      *models.User      `json:"user"`
	FromUser  *models.User      `json:"from_user"`
	Scene     *models.Scene     `json:"scene"`
	Equipment *models.Equipment `json:"equipment"`
}

// @Title Beinvite
// @Descripton 受邀请列表
// @param status	path	string		false	"分享状态 0 未确认 1  拒绝 2 解除分享 3"
// @router /beinvite [get]
func (c *FamilyController) Beinvite() {
	var (
		status    int
		page      int
		err       error
		p         map[string]interface{}
		lists     []*models.Family
		beinvites []*familyList
	)

	p = map[string]interface{}{"user_id": c.User.Id}
	if page == 0 {
		page = 1
	}

	c.Ctx.Input.Bind(&page, "page")
	if status, err = c.GetInt("status", -1); err != nil {
		c.Error(errmsg.ErrResponseParameter)
		return
	}
	if status != -1 {
		p["status"] = status
	}

	if lists, err = models.GetAllFamily(p, page); err != nil {
		logs.Error(err)
		c.Error(errmsg.ErrResponseSystem)
		return
	}

	if lists == nil {
		c.Success(nil)
		return
	}

	for _, v := range lists {
		bein := &familyList{
			Family: *v,
		}
		bein.User, _ = models.GetUserById(v.UserId)
		if len(v.SceneId) > 0 {
			bein.Scene, _ = models.GetSceneById(v.SceneId)
		}
		bein.FromUser, _ = models.GetUserById(v.FromUserId)
		bein.Equipment, _ = models.GetEquipmentBySta(v.Sta)
		beinvites = append(beinvites, bein)
	}

	c.Success(beinvites)
}

// @Title Invite
// @Descripton 设备邀请列表
// @param sta	path	string		true	"设备码"
// @router /invite/:sta [get]
func (c *FamilyController) Invite() {
	var (
		sta     string
		eq      *models.Equipment
		err     error
		lists   []*models.Family
		invites []*familyList
		p       map[string]interface{}
	)

	sta = c.GetString(":sta")

	// 判断操作权限
	if eq, err = models.GetEquipmentBySta(sta); err != nil {
		logs.Error(err)
		c.Error(errmsg.ErrResponseSystem)
		return
	}
	if eq.UserId != c.User.Id {
		logs.Info(errmsg.ErrResponseAuth)
		c.Error(errmsg.ErrResponseAuth)
		return
	}

	p = map[string]interface{}{"sta": sta, "status__in": []int{0, 1}}
	if lists, err = models.GetAllFamily(p, 0); err != nil {
		logs.Info(err)
		c.Error(errmsg.ErrResponseSystem)
		return
	}

	if lists == nil {
		c.Success(nil)
		return
	}

	for _, v := range lists {
		in := &familyList{
			Family: *v,
		}
		in.User, _ = models.GetUserById(v.UserId)
		if len(v.SceneId) > 0 {
			in.Scene, _ = models.GetSceneById(v.SceneId)
		}
		in.FromUser, _ = models.GetUserById(v.FromUserId)
		in.Equipment, _ = models.GetEquipmentBySta(v.Sta)
		invites = append(invites, in)
	}

	c.Success(invites)
}

// @Title Relieve
// @Descripton 设备解除分享
// @param id	path	string		true	"邀请id"
// @router /relieve/:id [delete]
func (c *FamilyController) Relieve() {
	var (
		id  string
		err error
		sh  *models.Family
	)

	id = c.GetString(":id")
	if sh, err = models.GetFamilyById(id); err != nil {
		logs.Info(err)
		c.Error(errmsg.ErrResponseSystem)
		return
	}
	if sh == nil {
		err = errors.New("分享不存在")
		logs.Info(err)
		c.Error(errmsg.ErrResponseFail)
		return
	}
	if sh.Status != models.Family_Wait && sh.Status != models.Family_Accept {
		logs.Info(errmsg.ErrResponseFail)
		c.Error(errmsg.ErrResponseFail)
		return
	}
	if sh.FromUserId != c.User.Id {
		logs.Info(errmsg.ErrResponseAuth)
		c.Error(errmsg.ErrResponseAuth)
		return
	}
	if sh.Status == models.Family_Relieve {
		c.Error(errmsg.ErrResponseFail)
		return
	}

	if err = models.RelieveFamilyBySta(sh.Sta, sh.UserId); err != nil {
		logs.Error(err)
		c.Error(errmsg.ErrResponseFail)
		return
	}

	c.Success(nil)
}

// @Title Confirm
// @Descripton 确认邀请
// @param id		path	string		true	"邀请id"
// @param accept	form	int			true	"0 拒绝邀请 1 接受邀请"
// @param name		form	string		true	"自定义设备名称"
// @param scene_id	form	string		true	"场景id"
// @router /confirm/:id [post]
func (c *FamilyController) Confirm() {
	var (
		id      string
		err     error
		f       *models.Family
		s       *models.Scene
		eq      *models.Equipment
		accept  int
		content string
		vali    validation.Validation
		count   int
	)

	// 绑定数据
	c.Ctx.Input.Bind(&id, ":id")
	c.Ctx.Input.Bind(&accept, "accept")
	if accept != 0 && accept != 1 {
		logs.Error(err)
		c.Error(errmsg.ErrResponseParameter)
		return
	}

	if f, err = models.GetFamilyById(id); err != nil {
		logs.Error(err)
		c.Error(errmsg.ErrResponseSystem)
		return
	}
	if f == nil {
		logs.Error(errmsg.ErrResponseNotFound)
		c.Error(errmsg.ErrResponseFail)
		return
	}
	if f.UserId != c.User.Id {
		logs.Error(errmsg.ErrResponseAuth)
		c.Error(errmsg.ErrResponseAuth)
		return
	}
	if f.Status != models.Family_Wait {
		logs.Error(errors.New("不是等待确认状态"))
		c.Error(errmsg.ErrResponseFail)
		return
	}

	// 拒绝邀请
	if accept == 0 {
		content = fmt.Sprintf("%s已拒绝您的分享请求", c.User.NickName)

		// 修改设备状态
		if err = models.UpdateFamilyStatusById(id, models.Family_Refuse); err != nil {
			logs.Error(err)
			c.Error(errmsg.ErrResponseSystem)
			return
		}
	} else { // 接受邀请
		content = fmt.Sprintf("%s已通过您的分享请求", c.User.NickName)

		if err = c.ParseData(f); err != nil {
			logs.Error(err)
			c.Error(errmsg.ErrResponseParameter)
			return
		}

		vali = validation.Validation{}
		vali.Required(f.Name, "name").Message("设备名称不能为空")
		vali.Required(f.SceneId, "scene_id").Message("请选择场景")
		if vali.HasErrors() {
			logs.Error(vali.Errors[0])
			c.Error(vali.Errors[0])
			return
		}

		// 检测设备是否存在
		if eq, err = models.GetEquipmentBySta(f.Sta); err != nil {
			logs.Error(err)
			c.Error(errmsg.ErrResponseSystem)
			return
		}
		if eq == nil {
			err = errors.New("设备不存在")
			logs.Error(err)
			c.Error(err)
			return
		}

		// 检测场景是否存在
		if s, err = models.GetSceneById(f.SceneId); err != nil {
			logs.Error(err)
			c.Error(errmsg.ErrResponseSystem)
			return
		}
		if s == nil {
			err = errors.New("场景不存在")
			logs.Info(err)
			c.Error(err)
			return
		}

		// 检测场景是否已存在该设备名称
		if count, err = models.GetEquipmentCountByUid(f.UserId,
			map[string]interface{}{
				"scene_id": f.SceneId,
				"name":     f.Name,
			}); err != nil {
			logs.Error(err)
			c.Error(errmsg.ErrResponseSystem)
			return
		}
		if count > 0 {
			err = errors.New("设备名称已存在")
			logs.Info(err)
			c.Error(err)
			return
		}

		f.Status = models.Family_Accept
		if !models.UpdateFamily(f) {
			c.Error(errmsg.ErrResponseFail)
			return
		}
	}

	// 推送消息
	models.PushMessage(f.FromUserId, content, "message")
	c.Success(nil)
}
